package com.tuanzi.loan.business.repository.product.product.impl;

import com.tuanzi.loan.business.constants.DictionaryCode;
import com.tuanzi.loan.business.entity.product.product.LoanProductInfo;
import com.tuanzi.loan.business.repository.product.product.custom.LoanProductInfoRepositoryCustom;
import com.tuanzi.loan.business.service.system.DictionaryService;
import com.tuanzi.loan.core.repository.JOOQBaseRepository;
import com.tuanzi.loan.generated.jooq.loan.tables.records.LoanProductInfoRecord;
import com.tuanzi.loan.vo.request.product.product.LoanProductInfoSearchRequest;
import com.tuanzi.loan.vo.response.product.product.LoanProductInfoSearchResponse;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.jooq.*;
import org.jooq.impl.DSL;
import org.jooq.impl.TableImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.tuanzi.loan.generated.jooq.loan.Tables.*;

/**
 * @author Ray 2017/09/21
 */
@SuppressWarnings({ "rawtypes" })
public class LoanProductInfoRepositoryImpl extends JOOQBaseRepository implements LoanProductInfoRepositoryCustom {

	@Autowired
	private DictionaryService dictionaryService;

	@Override
	protected TableImpl getTable() {
		return LOAN_PRODUCT_INFO;
	}

	@Override
	public Page<LoanProductInfoSearchResponse> list(LoanProductInfoSearchRequest searchRequest, Pageable pageable) {

		contains(LOAN_PRODUCT_INFO.NAME, searchRequest.getName());
		contains(LOAN_PRODUCT_INFO.ID, searchRequest.getActivityId());
		contains(LOAN_PRODUCT_INFO.STATUS, searchRequest.getStatus());
		if (searchRequest.getAutoOnline() != null && searchRequest.getAutoOnline() == 1){
			isNotNull(LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME);
		}
		if (searchRequest.getAutoOnline() != null && searchRequest.getAutoOnline() == 0){
			isNull(LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME);
			isNull(LOAN_PRODUCT_INFO.EVERY_DAY_OFFLINE_TIME);
		}
		eq(LOAN_PRODUCT_INFO.RECOMMEND_TYPE, searchRequest.getAlternate());
		eq(LOAN_PRODUCT_INFO.LARGE_COMMON_PRODUCT, searchRequest.getParentPrdid());

		orderBy(LOAN_PRODUCT_INFO.UPDATE_TIME, Sort.Direction.DESC);
		orderBy(LOAN_PRODUCT_INFO.CREATE_TIME, Sort.Direction.DESC);

		return search(pageable, new LoanProductInfoSearchResponseRecordMapper());
	}

	private final class LoanProductInfoSearchResponseRecordMapper implements RecordMapper<Record, LoanProductInfoSearchResponse> {

		@Override
		public LoanProductInfoSearchResponse map(Record record) {
			LoanProductInfoSearchResponse response = new LoanProductInfoSearchResponse();
			response.setId(record.get(LOAN_PRODUCT_INFO.ID));
			response.setName(record.get(LOAN_PRODUCT_INFO.NAME));
			response.setLogo(record.get(LOAN_PRODUCT_INFO.LOGO));
			response.setPosition(record.get(LOAN_PRODUCT_INFO.POSITION));
			response.setStatus(record.get(LOAN_PRODUCT_INFO.STATUS));
			response.setUpdator(record.get(LOAN_PRODUCT_INFO.UPDATOR));
			response.setUpdateTime(record.get(LOAN_PRODUCT_INFO.UPDATE_TIME));
			response.setCreateTime(record.get(LOAN_PRODUCT_INFO.CREATE_TIME));
			response.setDailyClickUvLimitation(record.get(LOAN_PRODUCT_INFO.DAY_LIMIT_CLICK_UV));
			response.setDailyClickUvRemaining(record.get(LOAN_PRODUCT_INFO.DAILY_CLICK_UV_REMAINING));
			Integer recommendType = record.get(LOAN_PRODUCT_INFO.RECOMMEND_TYPE);
			Map<String, String> listMapByCode = dictionaryService.listMapByCode(DictionaryCode.RECOMMEND_POOL_TYPE);
			if (listMapByCode != null){
				response.setType(listMapByCode.get(recommendType+""));
			}
			String large_product = record.get(LOAN_PRODUCT_INFO.LARGE_COMMON_PRODUCT);
			Map<String, String> parentProdByCode = dictionaryService.listMapByCode(DictionaryCode.LARGE_COMMON_PRODUCT);
			if (parentProdByCode != null){
				response.setLarge_products(parentProdByCode.get(large_product));
			}
			response.setAutoOnlineTime(record.get(LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME));
			return response;
		}
	}

	@Override
	public List<LoanProductInfoSearchResponse> listAllUnionProductInfo() {
		neq(LOAN_PRODUCT_INFO.UNION_TYPE, 0);
		return search(new LoanProductInfoSearchResponseRecordMapper());
	}

	@Override
	public List<LoanProductInfo> listAllProductInfo() {
		List<LoanProductInfo> productInfos = dslContext.select(LOAN_PRODUCT_INFO.ID, LOAN_PRODUCT_INFO.NAME,LOAN_PRODUCT_INFO.DAY_LIMIT_CLICK_UV,LOAN_PRODUCT_INFO.STATUS,
				LOAN_PRODUCT_INFO.DAILY_CLICK_UV_REMAINING,LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME,LOAN_PRODUCT_INFO.EVERY_DAY_OFFLINE_TIME,LOAN_PRODUCT_INFO.PREPAY_OFF_LINE,LOAN_PRODUCT_INFO.STATUS).from(LOAN_PRODUCT_INFO).fetchInto(LoanProductInfo.class);
		return productInfos;
	}

	@Override
	public List<LoanProductInfo> listAllProductInfoByCompanyId(Long companyId) {
		List<LoanProductInfo> productInfoList = dslContext.select(LOAN_PRODUCT_INFO.ID, LOAN_PRODUCT_INFO.NAME).from(LOAN_PRODUCT_INFO)
				.where(LOAN_PRODUCT_INFO.COMPANY_ID.eq(companyId)).fetchInto(LoanProductInfo.class);
		return productInfoList;
	}

	@Override
	public void deleteBy(Long prdId) {
		// 删除产品和其子产品
		int execute = dslContext.delete(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.ID.eq(prdId)).execute();
		if (execute > 0) {
			dslContext.delete(LOAN_ADVERT).where(LOAN_ADVERT.ACTIVITY_ID.eq(prdId)).execute();
			dslContext.delete(LOAN_TOPIC_PRODUCT).where(LOAN_TOPIC_PRODUCT.PRODUCT_ID.eq(prdId)).execute();
		}
	}

	@Override
	public List<Long> getTopicIdBy(Long prdId) {
		return dslContext.selectDistinct(LOAN_TOPIC_PRODUCT.TOPIC_ID).from(LOAN_TOPIC_PRODUCT).where(LOAN_TOPIC_PRODUCT.PRODUCT_ID.eq(prdId)).fetchInto(Long.class);
	}

	@Override
	public List<Long> getAdvertIdBy(Long prdId) {
		return dslContext.selectDistinct(LOAN_ADVERT.ID).from(LOAN_ADVERT).where(LOAN_ADVERT.ACTIVITY_ID.eq(prdId)).fetchInto(Long.class);
	}

	@Override
	public Long countOnline(LoanProductInfoSearchRequest searchRequest) {
		if (!StringUtils.isEmpty(searchRequest.getParentPrdid())){
			return dslContext.selectCount().from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.STATUS.eq(1).and(LOAN_PRODUCT_INFO.LARGE_COMMON_PRODUCT.eq(searchRequest.getParentPrdid()))).fetchOneInto(Long.class);
		}
		return dslContext.selectCount().from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.STATUS.eq(1)).fetchOneInto(Long.class);
	}

	@Override
	public Long sumDailyClickUvLimitationByOnline(LoanProductInfoSearchRequest searchRequest) {
		Record record = dslContext.select(DSL.sum(LOAN_PRODUCT_INFO.DAY_LIMIT_CLICK_UV)).from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.STATUS.eq(1))
				.fetchOne();
		return record == null ? 0L : record.into(Long.class);
	}

	@Override
	public Long sumDailyClickUvLimitation(LoanProductInfoSearchRequest searchRequest) {
		Record record;
		if (!StringUtils.isEmpty(searchRequest.getParentPrdid())){
			record = dslContext.select(DSL.sum(LOAN_PRODUCT_INFO.DAY_LIMIT_CLICK_UV)).from(LOAN_PRODUCT_INFO)
					.where(LOAN_PRODUCT_INFO.LARGE_COMMON_PRODUCT.eq(searchRequest.getParentPrdid())).fetchOne();
		}else{
			record = dslContext.select(DSL.sum(LOAN_PRODUCT_INFO.DAY_LIMIT_CLICK_UV)).from(LOAN_PRODUCT_INFO)
					.fetchOne();
		}

		return record == null ? 0L : record.into(Long.class);
	}

	@Override
	public Long sumDailyClickUvRemainingByOnelin(LoanProductInfoSearchRequest searchRequest) {
		Record record;
		if (!StringUtils.isEmpty(searchRequest.getParentPrdid())){
			record = dslContext.select(DSL.sum(LOAN_PRODUCT_INFO.DAILY_CLICK_UV_REMAINING)).from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.LARGE_COMMON_PRODUCT.eq(searchRequest.getParentPrdid())).fetchOne();
		}else{
			record = dslContext.select(DSL.sum(LOAN_PRODUCT_INFO.DAILY_CLICK_UV_REMAINING)).from(LOAN_PRODUCT_INFO).fetchOne();
		}
		return record == null ? 0L : record.into(Long.class);
	}

	@Override
	public Long sumDailyClickUvLimitationByOnlineOrAutoOnline() {
		Record record = dslContext.select(DSL.sum(LOAN_PRODUCT_INFO.DAY_LIMIT_CLICK_UV)).from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.STATUS.eq(1))
				.or(LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME.isNotNull()).fetchOne();
		return record == null ? 0L : record.into(Long.class);
	}

	@Override
	public Long sumDailyClickUvRemainingByOnelinOrAutoOnline() {
		Record record = dslContext.select(DSL.sum(LOAN_PRODUCT_INFO.DAILY_CLICK_UV_REMAINING)).from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.STATUS.eq(1))
				.or(LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME.isNotNull()).fetchOne();
		return record == null ? 0L : record.into(Long.class);
	}

	@Override
	public void updateLoanProductInfo(LoanProductInfo loanProductInfo) {
		dslContext.update(LOAN_PRODUCT_INFO)
				.set(LOAN_PRODUCT_INFO.STATUS, loanProductInfo.getStatus())
				.set(LOAN_PRODUCT_INFO.DAILY_CLICK_UV_REMAINING, loanProductInfo.getDayRemainingClickUv())
//				.set(LOAN_PRODUCT_INFO.UPDATE_TIME,new Timestamp(System.currentTimeMillis()))
//				.set(LOAN_PRODUCT_INFO.UPDATOR,"系统操作")
				.where(LOAN_PRODUCT_INFO.ID.eq(loanProductInfo.getId()))
				.execute();
	}

	@Override
	public Long countAutoOnline(LoanProductInfoSearchRequest searchRequest) {
		Long count;
		if (!StringUtils.isEmpty(searchRequest.getParentPrdid())){
			count = dslContext.selectCount().from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME.isNotNull().and(LOAN_PRODUCT_INFO.LARGE_COMMON_PRODUCT.eq(searchRequest.getParentPrdid()))).fetchOneInto(Long.class);
		}else{
			count = dslContext.selectCount().from(LOAN_PRODUCT_INFO).where(LOAN_PRODUCT_INFO.EVERY_DAY_ONLINE_TIME.isNotNull()).fetchOneInto(Long.class);
		}
		return count;
	}
}